package comm;
//Build the message that has to be sent through the socket

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import store.storage;
import utils.*;

public class MessageBuilder 
{
	private byte[] data;
	private Convert conv;
	
	//Constants used to indicate message types
	private static final byte CMD_UPDATE			= 1;	//update the server's IP table
	private static final byte CMD_ACK_JOIN	        = 2;	//Acknowledge request from client	
	private static final byte CMD_ACK_REJECT        = 3;	//Reject join request from client
	private static final byte CMD_REQ_JOIN		    = 4;	//Send request for joining group
	private static final byte CMD_START_RECORD		= 5;	//start recording
	private static final byte CMD_STOP_RECORD      	= 6;	//stop recording
	private static final byte CMD_KEY		      	= 7;	//send key
	private static final byte CMD_REC_FILE	      	= 8;	//Contains the recorded file 
	private static final byte CMD_REGISTER			= 9;	//Registers the clients with the server
	private static final byte CMD_DISCONNECT		= 10;	//Request for disconnecting from the group
	private static final byte CMD_TEST_MIX			= 11;	//Test the Mixing Capabilities
	
	
	//Send the message using the client socket
	public void sendMessage(String ip)
	{
		new MyClient(this.data, ip, 5000);
	}
	
	public MessageBuilder()
	{
		conv = new Convert();	//Initialize object for Convert class
	}

	//Register the client details at the Server
	public storage registerServer(String ip)
	{
		storage myip = new storage();
		
		try 
		{
			//Generate the loacl host IP and set the IP address
			myip.setIp(InetAddress.getLocalHost().getHostAddress());
		} 
		catch (UnknownHostException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		myip.setrole("participant");	//set the role of client to participant
		byte[] mainData = conv.toByteArray(myip);	
		data = new byte[mainData.length + 1];
		data[0] = CMD_REGISTER;			//Append message type to the data
		System.arraycopy(mainData, 0, data, 1, mainData.length);	//Copy contents of mainData array to data array
		new MyClient(this.data, ip, 5001);	//Send data through the client
		return myip;

	}
	
	public void TestMix(String ip, Object key)
	{
		byte[] mainData = conv.toByteArray(key);
		data = new byte[mainData.length + 1];
		data[0] = MessageBuilder.CMD_TEST_MIX;	//Append message type to data
		System.arraycopy(mainData, 0, data, 1, mainData.length);
		this.sendMessage(ip);	//Send message using client
	}
	
	//Disconnect client from server
	public void disconnect(String ip)
	{
		data = new byte[1];
		data[0] = MessageBuilder.CMD_DISCONNECT;	//Append message type to the data 
		new MyClient(this.data, ip, 5001);	//Send message using client
	}
	
	//Update IP table at the server
	public void updateServer(storage g, String ip)
	{
		byte[] mainData = conv.toByteArray(g);
		data = new byte[mainData.length + 1];
		data[0] = MessageBuilder.CMD_UPDATE;	//Append message type to data
		System.arraycopy(mainData, 0, data, 1, mainData.length);	//Copy appended data to data array
		new MyClient(this.data, ip, 5001);	//Send message using client

	}
	
	//Acknowledge client's request to join
	public void ackJoin(String ip)
	{
		data = new byte[1];
		data[0] = MessageBuilder.CMD_ACK_JOIN;	//Append message type to data
		this.sendMessage(ip);	//Send message through client
		
	}
	
	//Reject join request from client
	public void rejectJoin(String ip)
	{
		data = new byte[1];
		data[0] = MessageBuilder.CMD_ACK_REJECT;	//Append message type to data
		this.sendMessage(ip);	//Send message using client
		
	}
	
	//Client sends request to join the group
	public void reqJoin(String Pin,String ip)
	{
		
		byte[] mainData = conv.toByteArray(Pin);
		data = new byte[mainData.length + 1];
		data[0] = MessageBuilder.CMD_REQ_JOIN;	//Append message to data
		System.arraycopy(mainData, 0, data, 1, mainData.length);
		this.sendMessage(ip);	//Send message using client
		
	}
	
	//Send key to the clients
	public void sendKey(Object key,String ip)
	{		
		byte[] mainData = conv.toByteArray(key);
		data = new byte[mainData.length + 1];
		data[0] = MessageBuilder.CMD_KEY;	//Append message type to data
		System.arraycopy(mainData, 0, data, 1, mainData.length);
		this.sendMessage(ip);	//Send message using client
	}
	
	//Send data that has the recorded file
	public void sendFile(Object File,String ip)
	{
		FileInputStream fis;
		try {
			fis = new FileInputStream((File) File);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
	        byte[] buf = new byte[1024];
	        for (int readNum; (readNum = fis.read(buf)) != -1;) {
                bos.write(buf, 0, readNum); 
	        }
	        byte[] mainData = bos.toByteArray();
	        data = new byte[mainData.length + 1];
			data[0] = MessageBuilder.CMD_REC_FILE;	//Append message type to data
			System.arraycopy(mainData, 0, data, 1, mainData.length);
			this.sendMessage(ip);	//Send message using client
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

        
        
        
		
		
		
	}
	
	//Start the recording process
	public void startRecord(String ip)
	{
		data = new byte[1];
		data[0] = MessageBuilder.CMD_START_RECORD;	//Append message type to data
		this.sendMessage(ip);	//Send message using client
	}
	
	//Stop the recording process
	public void stopRecord(String ip)
	{
		data = new byte[1];
		data[0] = MessageBuilder.CMD_STOP_RECORD;	//Append message to data
		this.sendMessage(ip);	//Send message using client
	}
	
}
